package top.seefly.cloudstream.demos;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.atomic.LongAdder;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;


/**
 * 编程模型
 * 1. Destination Binders
 *  负责提供余外部消息传递系统将集成的组件；
 *  由Spring Cloud Stream的扩展组件，负责提供必要的配置和实现，以促进与外部消息系统的集成；
 *  它负责链接，委派以及发送至生产者和消费者的消息以及来自生产者和消费者的消息路由，数据类型转换
 *  用户代码的调用；
 *
 * 2. Bindings
 * 外部消息系统和应用程序之间的桥梁，提供消息的生产和消费；
 * binding在外部消息系统和应用程序之间提供了一座桥梁
 *
 * 3. Message
 *  生产者和消费者用于与目标Binding通信的规范数据结构
 *
 *
 * 一个 supplier 按照配置的规则以一定的频率生产消息
 * 一个 Function 中间加工消息，同时用管道操作符追加一个Log用于打印消息
 * 一个 Consumer 最终的消费之
 * @author liujianxin
 * @date 2023/07/30 16:44
 */
//@Configuration
public class SupplierFunctionConsumerDemo {
    private LongAdder count = new LongAdder();


    /**
     * 这里就相当于数据源，1/次被框架调用， 把生产的字符串发送到消息队列
     * 现在不太明白，这东西哪有什么应用场景呢？ 给应用做心跳检测使用？？
     *
     * 可以通过配置 spring.integration.poller.fixedDelay 来改变输出频率
     * 当然这是全局的，也可以单独配置
     *
     * spring.cloud.stream.bindings.stringSupplier-out-0.producer.poller.fixed-delay
     * 这个是指定的
     */
    @Bean
    public Supplier<String> stringSupplier() {
        return () -> {
            count.increment();
            System.out.println();
            String msg = String.format("--%d msg  ",count.intValue());
            System.out.println("1 生产者: "+ msg);
            return msg;
        };
    }


    /**
     * 一个 Function 用于加工消息
     */
    @Bean
    public Function<String,String> append() {
        return (str) -> str + "__append";
    }


    /**
     * 一个Function 用于日志打印
     * 并且和上卖弄的append配合，用管道操作符链接
     */
    @Bean
    public Function<String,String> log() {
        return (data) -> {
            System.out.println("2 中间商: "+ data);
            return data;
        };
    }



    /**
     * 一开始的spring cloud stream是基于注解驱动的
     * 现在基于约定， 你在容器中注入了一个函数式对象(Function Consumer Suppl)
     * 他就认为你是要使spring cloud stream
     *
     * 这里的Consumer就相当与消息订阅，默认订阅的topic就是 log-in-0;
     * 这个topic很奇怪，log还能理解，是这个方法的名称，也是bean的name；
     * 后面的in-0是啥？
     *
     * 不知道对不对，可以这样想， 这个consumer函数，只接受一个参数进行消费；
     * 这个参数在spring cloud  stream的语境下 不就相当于 订阅指定topic中的数据吗？
     *
     * 如果用接受两个参数的函数，意思是同时订阅两个topic，然后合在一起消费；
     * 这时候就是 log-in-0 log-in-1
     *
     */
    @Bean
    public Consumer<String> consumer() {
        return data -> System.out.println("3 消费者: " + data);
    }


}
